home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Mac Magazin/MacEasy 1
/
Mac Magazin and MacEasy Magazine CD - Issue 01.iso
/
Sharewarebibliothek
/
Powermac
/
C64
/
SOURCE
/
Instructions.c
< prev
next >
Wrap
Text File
|
1994-06-06
|
13KB
|
378 lines
/*
Commodore 64 Emulator v0.4 Earle F. Philhower III
Copyright (C) 1993-4 (st916w9r@dunx1.ocs.drexel.edu)
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include "Processor.h"
#include "Instructions.h"
#include "Stack.h"
#include "Modes.h"
#include "Error.h"
/* Rather than using multiplication and division to do the BCD math, it's implemented
* with lookup tables--faster and easier to code in 68K assembly.
*/
unsigned char bcd2dec[256] =
{
/* 0x00 */ 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,
/* 0x10 */ 10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,
/* 0x20 */ 20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,
/* 0x30 */ 30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,
/* 0x40 */ 40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,
/* 0x50 */ 50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,
/* 0x60 */ 60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,
/* 0x70 */ 70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,
/* 0x80 */ 80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,
/* 0x90 */ 90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,
/* 0xA0 */ 100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,
/* 0xB0 */ 110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,
/* 0xC0 */ 120,121,122,123,124,125,126,127,128,129,130,131,132,133,134,135,
/* 0xD0 */ 130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,
/* 0xE0 */ 140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,
/* 0xF0 */ 150,151,152,153,154,155,156,157,158,159,160,161,162,163,164,165
};
unsigned char dec2bcd[100] =
{
0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,
0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,
0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,
0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,
0x40,0x41,0x42,0x43,0x44,0x45,0x46,0x47,0x48,0x49,
0x50,0x51,0x52,0x53,0x54,0x55,0x56,0x57,0x58,0x59,
0x60,0x61,0x62,0x63,0x64,0x65,0x66,0x67,0x68,0x69,
0x70,0x71,0x72,0x73,0x74,0x75,0x76,0x77,0x78,0x79,
0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,
0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99
};
void i00() {
PushWord(pc);
flags |= BKC;
Push(flags);
flags &= ~BKC;
pc=WordAt(IrqTo); }
void i01() { ORA(IndirectXAddr); pc++; }
void i05() { ORA(ZeroPageAddr); pc++; }
void i06() { ASL(ZeroPageAddr); pc++; }
void i08() { Push(flags); }
void i09() { a |= ImmediateByte(); FlagsNZ(a); pc++; }
void i0a() {
if (a&128) flags |= CAR;
else flags &= ~CAR;
a=a<<1;
FlagsNZ(a); }
void i0d() { ORA(AbsoluteAddr); pc+=2; }
void i0e() { ASL(AbsoluteAddr); pc+=2; }
void i10() { BCL(NEG); }
void i11() { ORA(IndirectYAddr); pc++; }
void i15() { ORA(ZeroPageXAddr); pc++; }
void i16() { ASL(ZeroPageXAddr); pc++; }
void i18() { CLR(CAR); }
void i19() { ORA(AbsoluteYAddr); pc+=2; }
void i1d() { ORA(AbsoluteXAddr); pc+=2; }
void i1e() { ASL(AbsoluteXAddr); pc+=2; }
void i20() { PushWord(pc+1); pc=WordAt(pc); }
void i21() { AND(IndirectXAddr); pc++; }
void i24() { BIT(ZeroPageAddr); pc++; }
void i25() { AND(ZeroPageAddr); pc++; }
void i26() { ROL(ZeroPageAddr); pc++; }
void i28() { flags = Pop(); }
void i29() { a &= ImmediateByte(); FlagsNZ(a); pc++; }
void i2a() {
if (flags&CAR) {
if ((a&128)==0) flags &=~CAR;
a=(a<<1)|1; }
else {
if(a&128)flags|=CAR;
a=a<<1; }
FlagsNZ(a);
}
void i2c() { BIT(AbsoluteAddr); pc+=2; }
void i2d() { AND(AbsoluteAddr); pc+=2; }
void i2e() { ROL(AbsoluteAddr); pc+=2; }
void i30() { BST(NEG); }
void i31() { AND(IndirectYAddr); pc++; }
void i35() { AND(ZeroPageXAddr); pc++; }
void i36() { ROL(ZeroPageXAddr); pc++; }
void i38() { SET(CAR); }
void i39() { AND(AbsoluteYAddr); pc+=2; }
void i3d() { AND(AbsoluteXAddr); pc+=2; }
void i3e() { ROL(AbsoluteXAddr); pc+=2; }
void i40() { flags=Pop(); PopWord(pc); }
void i41() { EOR(IndirectXAddr); pc++; }
void i45() { EOR(ZeroPageAddr); pc++; }
void i46() { LSR(ZeroPageAddr); pc++; }
void i48() { Push(a); }
void i49() { a ^= ImmediateByte(); FlagsNZ(a); pc++; }
void i4a() {
flags &=~(CAR+NEG+ZER);
if (a&1) flags |=CAR;
if (a=a>>1); else flags |=ZER;
}
void i4c() { pc=WordAt(pc); }
void i4d() { EOR(AbsoluteAddr); pc+=2; }
void i4e() { LSR(AbsoluteAddr); pc+=2; }
void i50() { BCL(OVF); }
void i51() { EOR(IndirectYAddr); pc++; }
void i55() { EOR(ZeroPageXAddr); pc++; }
void i56() { LSR(ZeroPageXAddr); pc++; }
void i58() { CLR(INT); }
void i59() { EOR(AbsoluteYAddr); pc+=2; }
void i5d() { EOR(AbsoluteXAddr); pc+=2; }
void i5e() { LSR(AbsoluteXAddr); pc+=2; }
void i60() { PopWord(pc); pc++; }
void i61() { ADC(IndirectXAddr); pc++; }
void i65() { ADC(ZeroPageAddr); pc++; }
void i66() { ROR(ZeroPageAddr); pc++; }
void i68() { a=Pop(); FlagsNZ(a); }
void i69() {
register word data;
data=ImmediateByte();
if (flags&DEC) {
data = bcd2dec[data]+bcd2dec[a]+((flags&CAR)?1:0);
flags &= ~(CAR+OVF+NEG+ZER);
if (data>99) {
flags|=CAR+OVF;
data -=100; }
if (data==0) flags |= ZER;
else flags |= data&128;
a=dec2bcd[data];}
else {
data += a+((flags&CAR)?1:0);
flags &= ~(CAR+OVF+NEG+ZER);
if (data>255) {
flags|=OVF+CAR;
data &=255; }
if (data==0) flags |= ZER;
else flags |= data&128;
a=data; }
pc++;
}
void i6a() {
if (flags&CAR) {
if ((a&1)==0) flags &=~CAR;
a=(a>>1)|128; }
else {
if(a&1) flags|=CAR;
a=a>>1; }
FlagsNZ(a);
}
void i6c() { register word ta; ta=WordAt(pc); pc=WordAt(ta); }
void i6d() { ADC(AbsoluteAddr); pc+=2; }
void i6e() { ROR(AbsoluteAddr); pc+=2; }
void i70() { BST(OVF); }
void i71() { ADC(IndirectYAddr); pc++; }
void i75() { ADC(ZeroPageXAddr); pc++; }
void i76() { ROR(ZeroPageXAddr); pc++; }
void i78() { SET(INT); }
void i79() { ADC(AbsoluteYAddr); pc+=2; }
void i7d() { ADC(AbsoluteXAddr); pc+=2; }
void i7e() { ROR(AbsoluteXAddr); pc+=2; }
void i81() { STA(IndirectXAddr); pc++; }
void i84() { STY(ZeroPageAddr); pc++; }
void i85() { STA(ZeroPageAddr); pc++; }
void i86() { STX(ZeroPageAddr); pc++; }
void i88() { y--; FlagsNZ(y); }
void i8a() { a=x; FlagsNZ(a); }
void i8c() { STY(AbsoluteAddr); pc+=2; }
void i8d() { STA(AbsoluteAddr); pc+=2; }
void i8e() { STX(AbsoluteAddr); pc+=2; }
void i90() { BCL(CAR); }
void i91() { STA(IndirectYAddr); pc++; }
void i94() { STY(ZeroPageXAddr); pc++; }
void i95() { STA(ZeroPageXAddr); pc++; }
void i96() { STX(ZeroPageYAddr); pc++; }
void i98() { a=y; FlagsNZ(a); }
void i99() { STA(AbsoluteYAddr); pc+=2; }
void i9a() { sp=x; }
void i9d() { STA(AbsoluteXAddr); pc+=2; }
void ia0() { y=ImmediateByte(); FlagsNZ(y); pc++; }
void ia1() { LDA(IndirectXAddr); pc++; }
void ia2() { x=ImmediateByte(); FlagsNZ(x); pc++; }
void ia4() { LDY(ZeroPageAddr); pc++; }
void ia5() { LDA(ZeroPageAddr); pc++; }
void ia6() { LDX(ZeroPageAddr); pc++; }
void ia8() { y=a; FlagsNZ(y); }
void ia9() { a=ImmediateByte(); FlagsNZ(a); pc++; }
void iaa() { x=a; FlagsNZ(x); }
void iac() { LDY(AbsoluteAddr); pc+=2; }
void iad() { LDA(AbsoluteAddr); pc+=2; }
void iae() { LDX(AbsoluteAddr); pc+=2; }
void ib0() { BST(CAR); }
void ib1() { LDA(IndirectYAddr); pc++; }
void ib4() { LDY(ZeroPageXAddr); pc++; }
void ib5() { LDA(ZeroPageXAddr); pc++; }
void ib6() { LDX(ZeroPageYAddr); pc++; }
void ib8() { CLR(OVF); }
void ib9() { LDA(AbsoluteYAddr); pc+=2; }
void iba() { x=sp; }
void ibc() { LDY(AbsoluteXAddr); pc+=2; }
void ibd() { LDA(AbsoluteXAddr); pc+=2; }
void ibe() { LDX(AbsoluteYAddr); pc+=2; }
void ic0() {
register byte tbyte;
tbyte=ImmediateByte();
flags &=~(CAR+ZER+NEG);
if (y==tbyte) flags |=CAR+ZER;
else if (y>tbyte) flags |=CAR;
else flags |=NEG;
pc++;
}
void ic1() { CMP(IndirectXAddr); pc++; }
void ic4() { CPY(ZeroPageAddr); pc++; }
void ic5() { CMP(ZeroPageAddr); pc++; }
void ic6() { DECR(ZeroPageAddr); pc++; }
void ic8() { y++; FlagsNZ(y); }
void ic9() {
register byte tbyte;
tbyte=ImmediateByte();
flags &=~(CAR+ZER+NEG);
if (a==tbyte) flags |=CAR+ZER;
else if (a>tbyte) flags |=CAR;
else flags |=NEG;
pc++;
}
void ica() { x--; FlagsNZ(x); }
void icc() { CPY(AbsoluteAddr); pc+=2; }
void icd() { CMP(AbsoluteAddr); pc+=2; }
void ice() { DECR(AbsoluteAddr); pc+=2; }
void id0() { BCL(ZER); }
void id1() { CMP(IndirectYAddr); pc++; }
void id5() { CMP(ZeroPageXAddr); pc++; }
void id6() { DECR(ZeroPageXAddr); pc++; }
void id8() { CLR(DEC); }
void id9() { CMP(AbsoluteYAddr); pc+=2; }
void idd() { CMP(AbsoluteXAddr); pc+=2; }
void ide() { DECR(AbsoluteXAddr); pc+=2; }
void ie0() {
register byte tbyte;
tbyte=ImmediateByte();
flags &=~(CAR+ZER+NEG);
if (x==tbyte) flags |=CAR+ZER;
else if (x>tbyte) flags |=CAR;
else flags |=NEG;
pc++;
}
void ie1() { SBC(IndirectXAddr); pc++; }
void ie4() { CPX(ZeroPageAddr); pc++; }
void ie5() { SBC(ZeroPageAddr); pc++; }
void ie6() { INCR(ZeroPageAddr); pc++; }
void ie8() { x++; FlagsNZ(x); }
void ie9() {
register int data;
data=ImmediateByte();
if (flags&DEC) {
data = bcd2dec[a]-bcd2dec[data]-((flags&CAR)?0:1);
flags &= ~(CAR+ZER+NEG+OVF);
if (data==0) flags |=ZER+CAR;
else if (data>0) flags |=CAR;
else {
flags|=NEG;
data +=100; }
a=dec2bcd[data]; }
else {
data = a-data-((flags&CAR)?0:1);
flags &=~(CAR+ZER+OVF+NEG);
if (data==0) flags |= ZER+CAR;
else if (data>0) flags |= CAR;
else flags|=OVF;
data &= 255;
flags |= data&128;
a=data; }
pc++;
}
void iea() {}
void iec() { CPX(AbsoluteAddr); pc+=2; }
void ied() { SBC(AbsoluteAddr); pc+=2; }
void iee() { INCR(AbsoluteAddr); pc+=2; }
void if0() { BST(ZER); }
void if1() { SBC(IndirectYAddr); pc++; }
void if5() { SBC(ZeroPageXAddr); pc++; }
void if6() { INCR(ZeroPageXAddr); pc++; }
void if8() { SET(DEC); }
void if9() { SBC(AbsoluteYAddr); pc+=2; }
void ifd() { SBC(AbsoluteXAddr); pc+=2; }
void ife() { INCR(AbsoluteXAddr); pc+=2; }
void iff() { TrapExecute(); }
void ini()
{
#ifdef MACSBUG
DebugStr("\pNonImplemented!");
#endif
pc++;
}
int InstructionInitialize()
{
return kNoError;
}
void (* instruct[256]) () = {
i00, i01, ini, ini, ini, i05, i06, ini,
i08, i09, i0a, ini, ini, i0d, i0e, ini,
i10, i11, ini, ini, ini, i15, i16, ini,
i18, i19, ini, ini, ini, i1d, i1e, ini,
i20, i21, ini, ini, i24, i25, i26, ini,
i28, i29, i2a, ini, i2c, i2d, i2e, ini,
i30, i31, ini, ini, ini, i35, i36, ini,
i38, i39, ini, ini, ini, i3d, i3e, ini,
i40, i41, ini, ini, ini, i45, i46, ini,
i48, i49, i4a, ini, i4c, i4d, i4e, ini,
i50, i51, ini, ini, ini, i55, i56, ini,
i58, i59, ini, ini, ini, i5d, i5e, ini,
i60, i61, ini, ini, ini, i65, i66, ini,
i68, i69, i6a, ini, i6c, i6d, i6e, ini,
i70, i71, ini, ini, ini, i75, i76, ini,
i78, i79, ini, ini, ini, i7d, i7e, ini,
ini, i81, ini, ini, i84, i85, i86, ini,
i88, ini, i8a, ini, i8c, i8d, i8e, ini,
i90, i91, ini, ini, i94, i95, i96, ini,
i98, i99, i9a, ini, ini, i9d, ini, ini,
ia0, ia1, ia2, ini, ia4, ia5, ia6, ini,
ia8, ia9, iaa, ini, iac, iad, iae, ini,
ib0, ib1, ini, ini, ib4, ib5, ib6, ini,
ib8, ib9, iba, ini, ibc, ibd, ibe, ini,
ic0, ic1, ini, ini, ic4, ic5, ic6, ini,
ic8, ic9, ica, ini, icc, icd, ice, ini,
id0, id1, ini, ini, ini, id5, id6, ini,
id8, id9, ini, ini, ini, idd, ide, ini,
ie0, ie1, ini, ini, ie4, ie5, ie6, ini,
ie8, ie9, iea, ini, iec, ied, iee, ini,
if0, if1, ini, ini, ini, if5, if6, ini,
if8, if9, ini, ini, ini, ifd, ife, iff};
byte cycletime[256]={
/*00*/ 7, 6, 0, 0, 0, 3, 5, 0, 3, 2, 2, 0, 0, 4, 6, 0,
/*10*/ 3, 5, 0, 0, 0, 4, 6, 0, 2, 5, 0, 0, 0, 5, 7, 0,
/*20*/ 6, 6, 0, 0, 3, 3, 5, 0, 4, 2, 2, 0, 4, 4, 6, 0,
/*30*/ 3, 5, 0, 0, 0, 4, 6, 0, 2, 4, 0, 0, 0, 4, 7, 0,
/*40*/ 6, 6, 0, 0, 0, 3, 5, 0, 3, 2, 2, 0, 3, 4, 6, 0,
/*50*/ 3, 6, 0, 0, 0, 3, 6, 0, 2, 5, 0, 0, 0, 5, 7, 0,
/*60*/ 6, 6, 0, 0, 0, 3, 5, 0, 4, 2, 2, 0, 5, 4, 6, 0,
/*70*/ 3, 6, 0, 0, 0, 4, 6, 0, 2, 5, 0, 0, 0, 5, 7, 0,
/*80*/ 0, 6, 0, 0, 6, 3, 3, 0, 2, 0, 2, 0, 4, 4, 4, 0,
/*90*/ 2, 6, 0, 0, 4, 4, 4, 0, 2, 5, 2, 0, 0, 5, 0, 0,
/*A0*/ 2, 6, 2, 0, 3, 3, 3, 0, 2, 2, 2, 0, 4, 4, 4, 0,
/*B0*/ 3, 6, 0, 0, 4, 4, 4, 0, 2, 5, 2, 0, 5, 5, 5, 0,
/*C0*/ 2, 6, 0, 0, 3, 3, 5, 0, 2, 2, 2, 0, 4, 4, 6, 0,
/*D0*/ 3, 6, 0, 0, 0, 4, 6, 0, 2, 5, 0, 0, 0, 5, 7, 0,
/*E0*/ 2, 6, 0, 0, 3, 3, 5, 0, 2, 2, 2, 0, 4, 4, 6, 0,
/*F0*/ 3, 6, 0, 0, 0, 4, 6, 0, 2, 5, 0, 0, 0, 5, 7, 1 };